1 module models; 2 3 import std.typecons : Nullable; 4 import std.json : JSONValue, JSONType, parseJSON; 5 import std.format; 6 import std.algorithm : map; 7 import std.array : array; 8 import std.traits; 9 import std.meta : Filter, staticMap; 10 11 enum AlignContent: string { 12 flexStart = "flex-start", 13 flexEnd = "flex-end", 14 center = "center", 15 spaceBetween = "space-between", 16 spaceAround = "space-around", 17 spaceEvenly = "space-evenly", 18 stretch = "stretch", 19 inherit = "inherit", 20 initial = "initial", 21 unset = "unset" 22 } 23 24 enum AlignItems: string { 25 flexStart = "flex-start", 26 flexEnd = "flex-end", 27 center = "center", 28 baseline = "baseline", 29 stretch = "stretch", 30 inherit = "inherit", 31 initial = "initial", 32 unset = "unset" 33 } 34 35 enum AlignSelf: string { 36 auto_ = "auto", 37 flexStart = "flex-start", 38 flexEnd = "flex-end", 39 center = "center", 40 baseline = "baseline", 41 stretch = "stretch", 42 inherit = "inherit", 43 initial = "initial", 44 unset = "unset" 45 } 46 47 enum JustifyContent: string { 48 flexStart = "flex-start", 49 flexEnd = "flex-end", 50 center = "center", 51 spaceBetween = "space-between", 52 spaceAround = "space-around", 53 inherit = "inherit", 54 initial = "initial", 55 unset = "unset" 56 } 57 58 enum Overflow: string { 59 visible = "visible", 60 hidden = "hidden", 61 scroll = "scroll", 62 auto_ = "auto", 63 inherit = "inherit", 64 initial = "initial", 65 unset = "unset" 66 } 67 68 enum Visibility: string { 69 visible = "visible", 70 hidden = "hidden", 71 inherit = "inherit", 72 initial = "initial", 73 unset = "unset" 74 } 75 76 enum BoxStyle: string { 77 success = "success", 78 info = "info", 79 warning = "warning", 80 danger = "danger", 81 none = "" 82 } 83 84 enum ButtonStyle: string { 85 primary = "primary", 86 success = "success", 87 info = "info", 88 warning = "warning", 89 danger = "danger", 90 none = "" 91 } 92 93 enum Orientation : string { 94 horizontal = "horizontal", 95 vertical = "vertical" 96 } 97 // NOTE: the enums above aren't used in the models below. Instead plain strings are used. 98 // This is because of https://issues.dlang.org/show_bug.cgi?id=20410 99 // Effectively sumtype (by use of ReplaceTypeUnless) decays them into string, causing errors 100 101 // Models can reference to another Widget. The reference is a prepended string to a Widget's commId 102 auto makeReference(string commId) @safe { 103 return "IPY_MODEL_"~commId; 104 } 105 106 struct Reference(T) { 107 string value; 108 alias value this; 109 } 110 111 alias typeOf(alias T) = typeof(T); 112 // To instantiate a Widget!Model we need to also instantiate a Widget!T for each model that is referenced. 113 // This template exposed Names and Types which contain the name and type of each Referenced model for a given Model. 114 template getReferenceModels(T) { 115 enum isReference(string name) = is(typeof(__traits(getMember, T, name)) : Reference!R, R); 116 alias getSymbol(string name) = __traits(getMember, T, name); 117 alias extractModelType(T) = TemplateArgsOf!(T)[0]; 118 alias Names = Filter!(isReference, __traits(allMembers, T)); 119 alias Types = staticMap!(extractModelType, staticMap!(typeOf,staticMap!(getSymbol, Names))); 120 } 121 122 alias BarStyle = BoxStyle; 123 124 struct LayoutModel { 125 enum _model_module = "@jupyter-widgets/base"; // The namespace for the model. 126 enum _model_module_version = "1.0.0"; // A semver requirement for namespace version containing the model. 127 enum _model_name = "LayoutModel"; 128 enum _view_module = "@jupyter-widgets/base"; 129 enum _view_module_version = "1.0.0"; 130 enum _view_name = "LayoutView"; 131 Nullable!(string) align_content; // The align-content CSS attribute. 132 Nullable!(string) align_items; // The align-items CSS attribute. 133 Nullable!(string) align_self; // The align-self CSS attribute. 134 Nullable!(string) border; // The border CSS attribute. 135 Nullable!(string) bottom; // The bottom CSS attribute. 136 Nullable!(string) display; // The display CSS attribute. 137 Nullable!(string) flex; // The flex CSS attribute. 138 Nullable!(string) flex_flow; // The flex-flow CSS attribute. 139 Nullable!(string) height; // The height CSS attribute. 140 Nullable!(string) justify_content; // The justify-content CSS attribute. 141 Nullable!(string) left; // The left CSS attribute. 142 Nullable!(string) margin; // The margin CSS attribute. 143 Nullable!(string) max_height; // The max-height CSS attribute. 144 Nullable!(string) max_width; // The max-width CSS attribute. 145 Nullable!(string) min_height; // The min-height CSS attribute. 146 Nullable!(string) min_width; // The min-width CSS attribute. 147 Nullable!(string) order; // The order CSS attribute. 148 Nullable!(string) overflow; // The overflow CSS attribute. 149 Nullable!(string) overflow_x; // The overflow-x CSS attribute. 150 Nullable!(string) overflow_y; // The overflow-y CSS attribute. 151 Nullable!(string) padding; // The padding CSS attribute. 152 Nullable!(string) right; // The right CSS attribute. 153 Nullable!(string) top; // The top CSS attribute. 154 Nullable!(string) visibility; // The visibility CSS attribute. 155 Nullable!(string) width; // The width CSS attribute. 156 } 157 158 // TODO: WidgetModel[] is not implemented. Probably could be a IWidget[] 159 // struct AccordionModel { 160 // string[] _dom_classes; // CSS classes applied to widget DOM element 161 // enum _model_module = "@jupyter-widgets/controls"; 162 // enum _model_module_version = "1.2.0"; 163 // enum _model_name = "AccordionModel"; 164 // JSONValue _titles = {}; // Titles of the pages 165 // enum _view_module = "@jupyter-widgets/controls"; 166 // enum _view_module_version = "1.2.0"; 167 // enum _view_name = "AccordionView"; 168 // string box_style = BoxStyle.none; // Use a predefined styling for the box. 169 // WidgetModel[] children; // List of widget children 170 // Reference!LayoutModel layout; 171 // Nullable!(int) selected_index = 0; // The index of the selected page. This is either an integer selecting a particular sub-widget, or None to have no widgets selected. 172 // } 173 174 struct BoundedFloatTextModel { 175 string[] _dom_classes; // CSS classes applied to widget DOM element 176 enum _model_module = "@jupyter-widgets/controls"; 177 enum _model_module_version = "1.2.0"; 178 enum _model_name = "BoundedFloatTextModel"; 179 enum _view_module = "@jupyter-widgets/controls"; 180 enum _view_module_version = "1.2.0"; 181 enum _view_name = "FloatTextView"; 182 bool continuous_update = false; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 183 string description; // Description of the control. 184 bool disabled = false; // Enable or disable user changes 185 Reference!LayoutModel layout; 186 double max = 100.0; // Max value 187 double min = 0.0; // Min value 188 Nullable!(double) step; // Minimum step to increment the value 189 Reference!DescriptionStyleModel style; // Styling customizations 190 double value = 0.0; // Float value 191 } 192 193 struct BoundedIntTextModel { 194 string[] _dom_classes; // CSS classes applied to widget DOM element 195 enum _model_module = "@jupyter-widgets/controls"; 196 enum _model_module_version = "1.2.0"; 197 enum _model_name = "BoundedIntTextModel"; 198 enum _view_module = "@jupyter-widgets/controls"; 199 enum _view_module_version = "1.2.0"; 200 enum _view_name = "IntTextView"; 201 bool continuous_update = false; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 202 string description; // Description of the control. 203 bool disabled = false; // Enable or disable user changes 204 Reference!LayoutModel layout; 205 int max = 100; // Max value 206 int min = 0; // Min value 207 int step = 1; // Minimum step to increment the value 208 Reference!DescriptionStyleModel style; // Styling customizations 209 int value = 0; // Int value 210 } 211 212 // TODO: WidgetModel[] is not implemented. Probably could be a IWidget[] 213 // struct BoxModel { 214 // string[] _dom_classes; // CSS classes applied to widget DOM element 215 // enum _model_module = "@jupyter-widgets/controls"; 216 // enum _model_module_version = "1.2.0"; 217 // enum _model_name = "BoxModel"; 218 // enum _view_module = "@jupyter-widgets/controls"; 219 // enum _view_module_version = "1.2.0"; 220 // enum _view_name = "BoxView"; 221 // string box_style = BoxStyle.none; // Use a predefined styling for the box. 222 // WidgetModel[] children; // List of widget children 223 // Reference!LayoutModel layout; 224 // } 225 226 struct ButtonModel { 227 string[] _dom_classes; // CSS classes applied to widget DOM element 228 enum _model_module = "@jupyter-widgets/controls"; 229 enum _model_module_version = "1.2.0"; 230 enum _model_name = "ButtonModel"; 231 enum _view_module = "@jupyter-widgets/controls"; 232 enum _view_module_version = "1.2.0"; 233 enum _view_name = "ButtonView"; 234 string button_style = ButtonStyle.none; // Use a predefined styling for the button. 235 string description; // Button label. 236 bool disabled = false; // Enable or disable user changes. 237 string icon; // Font-awesome icon name, without the 'fa-' prefix. 238 Reference!LayoutModel layout; 239 Reference!ButtonStyleModel style; 240 string tooltip; // Tooltip caption of the button. 241 } 242 243 struct ButtonStyleModel { 244 enum _model_module = "@jupyter-widgets/controls"; 245 enum _model_module_version = "1.2.0"; 246 enum _model_name = "ButtonStyleModel"; 247 enum _view_module = "@jupyter-widgets/base"; 248 enum _view_module_version = "1.0.0"; 249 enum _view_name = "StyleView"; 250 Nullable!(string) button_color; // Color of the button 251 string font_weight; // Button text font weight. 252 } 253 254 struct CheckboxModel { 255 string[] _dom_classes; // CSS classes applied to widget DOM element 256 enum _model_module = "@jupyter-widgets/controls"; 257 enum _model_module_version = "1.2.0"; 258 enum _model_name = "CheckboxModel"; 259 enum _view_module = "@jupyter-widgets/controls"; 260 enum _view_module_version = "1.2.0"; 261 enum _view_name = "CheckboxView"; 262 string description; // Description of the control. 263 bool disabled = false; // Enable or disable user changes. 264 bool indent = true; // Indent the control to align with other controls with a description. 265 Reference!LayoutModel layout; 266 Reference!DescriptionStyleModel style; // Styling customizations 267 bool value = false; // Bool value 268 } 269 270 struct ColorPickerModel { 271 string[] _dom_classes; // CSS classes applied to widget DOM element 272 enum _model_module = "@jupyter-widgets/controls"; 273 enum _model_module_version = "1.2.0"; 274 enum _model_name = "ColorPickerModel"; 275 enum _view_module = "@jupyter-widgets/controls"; 276 enum _view_module_version = "1.2.0"; 277 enum _view_name = "ColorPickerView"; 278 bool concise = false; // Display short version with just a color selector. 279 string description; // Description of the control. 280 bool disabled = false; // Enable or disable user changes. 281 Reference!LayoutModel layout; 282 Reference!DescriptionStyleModel style; // Styling customizations 283 string value = "black"; // The color value. 284 } 285 286 struct ControllerAxisModel { 287 string[] _dom_classes; // CSS classes applied to widget DOM element 288 enum _model_module = "@jupyter-widgets/controls"; 289 enum _model_module_version = "1.2.0"; 290 enum _model_name = "ControllerAxisModel"; 291 enum _view_module = "@jupyter-widgets/controls"; 292 enum _view_module_version = "1.2.0"; 293 enum _view_name = "ControllerAxisView"; 294 Reference!LayoutModel layout; 295 double value = 0.0; // The value of the axis. 296 } 297 298 struct ControllerButtonModel { 299 string[] _dom_classes; // CSS classes applied to widget DOM element 300 enum _model_module = "@jupyter-widgets/controls"; 301 enum _model_module_version = "1.2.0"; 302 enum _model_name = "ControllerButtonModel"; 303 enum _view_module = "@jupyter-widgets/controls"; 304 enum _view_module_version = "1.2.0"; 305 enum _view_name = "ControllerButtonView"; 306 Reference!LayoutModel layout; 307 bool pressed = false; // Whether the button is pressed. 308 double value = 0.0; // The value of the button. 309 } 310 311 // struct ControllerModel { 312 // string[] _dom_classes; // CSS classes applied to widget DOM element 313 // enum _model_module = "@jupyter-widgets/controls"; 314 // enum _model_module_version = "1.2.0"; 315 // enum _model_name = "ControllerModel"; 316 // enum _view_module = "@jupyter-widgets/controls"; 317 // enum _view_module_version = "1.2.0"; 318 // enum _view_name = "ControllerView"; 319 // AxisModel[] axes; // The axes on the gamepad. 320 // ButtonModel[] buttons; // The buttons on the gamepad. 321 // bool connected = false; // Whether the gamepad is connected. 322 // int index = 0; // The id number of the controller. 323 // Reference!LayoutModel layout; 324 // string mapping; // The name of the control mapping. 325 // string name; // The name of the controller. 326 // double timestamp = 0.0; // The last time the data from this gamepad was updated. 327 // } 328 329 // TODO: Serialisation for Date is not implemented. Could use phobos' DateTime 330 // struct DatePickerModel { 331 // string[] _dom_classes; // CSS classes applied to widget DOM element 332 // enum _model_module = "@jupyter-widgets/controls"; 333 // enum _model_module_version = "1.2.0"; 334 // enum _model_name = "DatePickerModel"; 335 // enum _view_module = "@jupyter-widgets/controls"; 336 // enum _view_module_version = "1.2.0"; 337 // enum _view_name = "DatePickerView"; 338 // string description; // Description of the control. 339 // bool disabled = false; // Enable or disable user changes. 340 // Reference!LayoutModel layout; 341 // Reference!DescriptionStyleModel style; // Styling customizations 342 // Nullable!(Date) value; 343 // } 344 345 struct DescriptionStyleModel { 346 enum _model_module = "@jupyter-widgets/controls"; 347 enum _model_module_version = "1.2.0"; 348 enum _model_name = "DescriptionStyleModel"; 349 enum _view_module = "@jupyter-widgets/base"; 350 enum _view_module_version = "1.0.0"; 351 enum _view_name = "StyleView"; 352 string description_width; // Width of the description to the side of the control. 353 } 354 355 // TODO: the source and target fields should probably be a IWidget 356 // struct DirectionalLinkModel { 357 // enum _model_module = "@jupyter-widgets/controls"; 358 // enum _model_module_version = "1.2.0"; 359 // enum _model_name = "DirectionalLinkModel"; 360 // enum _view_module = "@jupyter-widgets/controls"; 361 // enum _view_module_version = "1.2.0"; 362 // Nullable!(string) _view_name; // Name of the view. 363 // array source; // The source (widget, 'trait_name') pair 364 // array target; // The target (widget, 'trait_name') pair 365 // } 366 367 struct DropdownModel { 368 string[] _dom_classes; // CSS classes applied to widget DOM element 369 enum _model_module = "@jupyter-widgets/controls"; 370 enum _model_module_version = "1.2.0"; 371 enum _model_name = "DropdownModel"; 372 string[] _options_labels; // The labels for the options. 373 enum _view_module = "@jupyter-widgets/controls"; 374 enum _view_module_version = "1.2.0"; 375 enum _view_name = "DropdownView"; 376 string description; // Description of the control. 377 bool disabled = false; // Enable or disable user changes 378 Nullable!(int) index; // Selected index 379 Reference!LayoutModel layout; 380 Reference!DescriptionStyleModel style; // Styling customizations 381 } 382 383 struct FloatLogSliderModel { 384 string[] _dom_classes; // CSS classes applied to widget DOM element 385 enum _model_module = "@jupyter-widgets/controls"; 386 enum _model_module_version = "1.2.0"; 387 enum _model_name = "FloatLogSliderModel"; 388 enum _view_module = "@jupyter-widgets/controls"; 389 enum _view_module_version = "1.2.0"; 390 enum _view_name = "FloatLogSliderView"; 391 double base = 10.0; // Base for the logarithm 392 bool continuous_update = true; // Update the value of the widget as the user is holding the slider. 393 string description; // Description of the control. 394 bool disabled = false; // Enable or disable user changes 395 Reference!LayoutModel layout; 396 double max = 4.0; // Max value for the exponent 397 double min = 0.0; // Min value for the exponent 398 string orientation = Orientation.horizontal; // Vertical or horizontal. 399 bool readout = true; // Display the current value of the slider next to it. 400 string readout_format = ".3g"; // Format for the readout 401 double step = 0.1; // Minimum step in the exponent to increment the value 402 Reference!SliderStyleModel style; 403 double value = 1.0; // Float value 404 } 405 406 struct FloatProgressModel { 407 string[] _dom_classes; // CSS classes applied to widget DOM element 408 enum _model_module = "@jupyter-widgets/controls"; 409 enum _model_module_version = "1.2.0"; 410 enum _model_name = "FloatProgressModel"; 411 enum _view_module = "@jupyter-widgets/controls"; 412 enum _view_module_version = "1.2.0"; 413 enum _view_name = "ProgressView"; 414 Nullable!(string) bar_style = Nullable!(string)(BarStyle.none); // Use a predefined styling for the progess bar. 415 string description; // Description of the control. 416 Reference!LayoutModel layout; 417 double max = 100.0; // Max value 418 double min = 0.0; // Min value 419 string orientation = Orientation.horizontal; // Vertical or horizontal. 420 Reference!ProgressStyleModel style; 421 double value = 0.0; // Float value 422 } 423 424 struct FloatRangeSliderModel { 425 string[] _dom_classes; // CSS classes applied to widget DOM element 426 enum _model_module = "@jupyter-widgets/controls"; 427 enum _model_module_version = "1.2.0"; 428 enum _model_name = "FloatRangeSliderModel"; 429 enum _view_module = "@jupyter-widgets/controls"; 430 enum _view_module_version = "1.2.0"; 431 enum _view_name = "FloatRangeSliderView"; 432 bool continuous_update = true; // Update the value of the widget as the user is sliding the slider. 433 string description; // Description of the control. 434 bool disabled = false; // Enable or disable user changes 435 Reference!LayoutModel layout; 436 double max = 100.0; // Max value 437 double min = 0.0; // Min value 438 string orientation = Orientation.horizontal; // Vertical or horizontal. 439 bool readout = true; // Display the current value of the slider next to it. 440 string readout_format = ".2f"; // Format for the readout 441 double step = 0.1; // Minimum step to increment the value 442 Reference!SliderStyleModel style; 443 double[2] value = [0.0, 1.0]; // Tuple of (lower, upper) bounds 444 } 445 446 struct FloatSliderModel { 447 string[] _dom_classes; // CSS classes applied to widget DOM element 448 enum _model_module = "@jupyter-widgets/controls"; 449 enum _model_module_version = "1.2.0"; 450 enum _model_name = "FloatSliderModel"; 451 enum _view_module = "@jupyter-widgets/controls"; 452 enum _view_module_version = "1.2.0"; 453 enum _view_name = "FloatSliderView"; 454 bool continuous_update = true; // Update the value of the widget as the user is holding the slider. 455 string description; // Description of the control. 456 bool disabled = false; // Enable or disable user changes 457 Reference!LayoutModel layout; 458 double max = 100.0; // Max value 459 double min = 0.0; // Min value 460 string orientation = Orientation.horizontal; // Vertical or horizontal. 461 bool readout = true; // Display the current value of the slider next to it. 462 string readout_format = ".2f"; // Format for the readout 463 double step = 0.1; // Minimum step to increment the value 464 Reference!SliderStyleModel style; 465 double value = 0.0; // Float value 466 } 467 468 struct FloatTextModel { 469 string[] _dom_classes; // CSS classes applied to widget DOM element 470 enum _model_module = "@jupyter-widgets/controls"; 471 enum _model_module_version = "1.2.0"; 472 enum _model_name = "FloatTextModel"; 473 enum _view_module = "@jupyter-widgets/controls"; 474 enum _view_module_version = "1.2.0"; 475 enum _view_name = "FloatTextView"; 476 bool continuous_update = false; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 477 string description; // Description of the control. 478 bool disabled = false; // Enable or disable user changes 479 Reference!LayoutModel layout; 480 Nullable!(double) step; // Minimum step to increment the value 481 Reference!DescriptionStyleModel style; // Styling customizations 482 double value = 0.0; // Float value 483 } 484 485 // TODO: WidgetModel[] is not implemented. Probably could be a IWidget[] 486 // struct HBoxModel { 487 // string[] _dom_classes; // CSS classes applied to widget DOM element 488 // enum _model_module = "@jupyter-widgets/controls"; 489 // enum _model_module_version = "1.2.0"; 490 // enum _model_name = "HBoxModel"; 491 // enum _view_module = "@jupyter-widgets/controls"; 492 // enum _view_module_version = "1.2.0"; 493 // enum _view_name = "HBoxView"; 494 // string box_style = BoxStyle.none; // Use a predefined styling for the box. 495 // WidgetModel[] children; // List of widget children 496 // Reference!LayoutModel layout; 497 // } 498 499 struct HTMLMathModel { 500 string[] _dom_classes; // CSS classes applied to widget DOM element 501 enum _model_module = "@jupyter-widgets/controls"; 502 enum _model_module_version = "1.2.0"; 503 enum _model_name = "HTMLMathModel"; 504 enum _view_module = "@jupyter-widgets/controls"; 505 enum _view_module_version = "1.2.0"; 506 enum _view_name = "HTMLMathView"; 507 string description; // Description of the control. 508 Reference!LayoutModel layout; 509 string placeholder = "\u200b"; // Placeholder text to display when nothing has been typed 510 Reference!DescriptionStyleModel style; // Styling customizations 511 string value; // String value 512 } 513 514 struct HTMLModel { 515 string[] _dom_classes; // CSS classes applied to widget DOM element 516 enum _model_module = "@jupyter-widgets/controls"; 517 enum _model_module_version = "1.2.0"; 518 enum _model_name = "HTMLModel"; 519 enum _view_module = "@jupyter-widgets/controls"; 520 enum _view_module_version = "1.2.0"; 521 enum _view_name = "HTMLView"; 522 string description; // Description of the control. 523 Reference!LayoutModel layout; 524 string placeholder = "\u200b"; // Placeholder text to display when nothing has been typed 525 Reference!DescriptionStyleModel style; // Styling customizations 526 string value; // String value 527 } 528 529 // TODO: Bytes is not yet defined. Could be ubyte[]. This also requires to implement the buffer_paths part of the ipywidget widget protocol. 530 // struct ImageModel { 531 // string[] _dom_classes; // CSS classes applied to widget DOM element 532 // enum _model_module = "@jupyter-widgets/controls"; 533 // enum _model_module_version = "1.2.0"; 534 // enum _model_name = "ImageModel"; 535 // enum _view_module = "@jupyter-widgets/controls"; 536 // enum _view_module_version = "1.2.0"; 537 // enum _view_name = "ImageView"; 538 // string format = "png"; // The format of the image. 539 // string height; // Height of the image in pixels. 540 // Reference!LayoutModel layout; 541 // Bytes value; // The image data as a byte string. 542 // string width; // Width of the image in pixels. 543 // } 544 545 struct IntProgressModel { 546 string[] _dom_classes; // CSS classes applied to widget DOM element 547 enum _model_module = "@jupyter-widgets/controls"; 548 enum _model_module_version = "1.2.0"; 549 enum _model_name = "IntProgressModel"; 550 enum _view_module = "@jupyter-widgets/controls"; 551 enum _view_module_version = "1.2.0"; 552 enum _view_name = "ProgressView"; 553 string bar_style = BarStyle.none; // Use a predefined styling for the progess bar. 554 string description; // Description of the control. 555 Reference!LayoutModel layout; 556 int max = 100; // Max value 557 int min = 0; // Min value 558 string orientation = Orientation.horizontal; // Vertical or horizontal. 559 Reference!ProgressStyleModel style; 560 int value = 0; // Int value 561 } 562 563 struct IntRangeSliderModel { 564 string[] _dom_classes; // CSS classes applied to widget DOM element 565 enum _model_module = "@jupyter-widgets/controls"; 566 enum _model_module_version = "1.2.0"; 567 enum _model_name = "IntRangeSliderModel"; 568 enum _view_module = "@jupyter-widgets/controls"; 569 enum _view_module_version = "1.2.0"; 570 enum _view_name = "IntRangeSliderView"; 571 bool continuous_update = true; // Update the value of the widget as the user is sliding the slider. 572 string description; // Description of the control. 573 bool disabled = false; // Enable or disable user changes 574 Reference!LayoutModel layout; 575 int max = 100; // Max value 576 int min = 0; // Min value 577 string orientation = Orientation.horizontal; // Vertical or horizontal. 578 bool readout = true; // Display the current value of the slider next to it. 579 string readout_format = "d"; // Format for the readout 580 int step = 1; // Minimum step that the value can take 581 Reference!SliderStyleModel style; // Slider style customizations. 582 double[2] value = [0, 1]; // Tuple of (lower, upper) bounds 583 } 584 585 struct IntSliderModel { 586 string[] _dom_classes; // CSS classes applied to widget DOM element 587 enum _model_module = "@jupyter-widgets/controls"; 588 enum _model_module_version = "1.2.0"; 589 enum _model_name = "IntSliderModel"; 590 enum _view_module = "@jupyter-widgets/controls"; 591 enum _view_module_version = "1.2.0"; 592 enum _view_name = "IntSliderView"; 593 bool continuous_update = true; // Update the value of the widget as the user is holding the slider. 594 string description; // Description of the control. 595 bool disabled = false; // Enable or disable user changes 596 Reference!LayoutModel layout; 597 int max = 100; // Max value 598 int min = 0; // Min value 599 string orientation = Orientation.horizontal; // Vertical or horizontal. 600 bool readout = true; // Display the current value of the slider next to it. 601 string readout_format = "d"; // Format for the readout 602 int step = 1; // Minimum step to increment the value 603 Reference!SliderStyleModel style; 604 int value = 0; // Int value 605 } 606 607 struct IntTextModel { 608 string[] _dom_classes; // CSS classes applied to widget DOM element 609 enum _model_module = "@jupyter-widgets/controls"; 610 enum _model_module_version = "1.2.0"; 611 enum _model_name = "IntTextModel"; 612 enum _view_module = "@jupyter-widgets/controls"; 613 enum _view_module_version = "1.2.0"; 614 enum _view_name = "IntTextView"; 615 bool continuous_update = false; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 616 string description; // Description of the control. 617 bool disabled = false; // Enable or disable user changes 618 Reference!LayoutModel layout; 619 int step = 1; // Minimum step to increment the value 620 Reference!DescriptionStyleModel style; // Styling customizations 621 int value = 0; // Int value 622 } 623 624 struct LabelModel { 625 string[] _dom_classes; // CSS classes applied to widget DOM element 626 enum _model_module = "@jupyter-widgets/controls"; 627 enum _model_module_version = "1.2.0"; 628 enum _model_name = "LabelModel"; 629 enum _view_module = "@jupyter-widgets/controls"; 630 enum _view_module_version = "1.2.0"; 631 enum _view_name = "LabelView"; 632 string description; // Description of the control. 633 Reference!LayoutModel layout; 634 string placeholder = "\u200b"; // Placeholder text to display when nothing has been typed 635 Reference!DescriptionStyleModel style; // Styling customizations 636 string value; // String value 637 } 638 639 // TODO: source and target should probably be a simple struct type 640 // struct LinkModel { 641 // enum _model_module = "@jupyter-widgets/controls"; 642 // enum _model_module_version = "1.2.0"; 643 // enum _model_name = "LinkModel"; 644 // enum _view_module = "@jupyter-widgets/controls"; 645 // enum _view_module_version = "1.2.0"; 646 // Nullable!(string) _view_name; // Name of the view. 647 // array source; // The source (widget, 'trait_name') pair 648 // array target; // The target (widget, 'trait_name') pair 649 // } 650 651 struct PasswordModel { 652 string[] _dom_classes; // CSS classes applied to widget DOM element 653 enum _model_module = "@jupyter-widgets/controls"; 654 enum _model_module_version = "1.2.0"; 655 enum _model_name = "PasswordModel"; 656 enum _view_module = "@jupyter-widgets/controls"; 657 enum _view_module_version = "1.2.0"; 658 enum _view_name = "PasswordView"; 659 bool continuous_update = true; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 660 string description; // Description of the control. 661 bool disabled = false; // Enable or disable user changes 662 Reference!LayoutModel layout; 663 string placeholder = "\u200b"; // Placeholder text to display when nothing has been typed 664 Reference!DescriptionStyleModel style; // Styling customizations 665 string value; // String value 666 } 667 668 struct PlayModel { 669 string[] _dom_classes; // CSS classes applied to widget DOM element 670 enum _model_module = "@jupyter-widgets/controls"; 671 enum _model_module_version = "1.2.0"; 672 enum _model_name = "PlayModel"; 673 bool _playing = false; // Whether the control is currently playing. 674 bool _repeat = false; // Whether the control will repeat in a continous loop. 675 enum _view_module = "@jupyter-widgets/controls"; 676 enum _view_module_version = "1.2.0"; 677 enum _view_name = "PlayView"; 678 string description; // Description of the control. 679 bool disabled = false; // Enable or disable user changes 680 int interval = 100; // The maximum value for the play control. 681 Reference!LayoutModel layout; 682 int max = 100; // Max value 683 int min = 0; // Min value 684 bool show_repeat = true; // Show the repeat toggle button in the widget. 685 int step = 1; // Increment step 686 Reference!DescriptionStyleModel style; // Styling customizations 687 int value = 0; // Int value 688 } 689 690 struct ProgressStyleModel { 691 enum _model_module = "@jupyter-widgets/controls"; 692 enum _model_module_version = "1.2.0"; 693 enum _model_name = "ProgressStyleModel"; 694 enum _view_module = "@jupyter-widgets/base"; 695 enum _view_module_version = "1.0.0"; 696 enum _view_name = "StyleView"; 697 Nullable!(string) bar_color; // Color of the progress bar. 698 string description_width; // Width of the description to the side of the control. 699 } 700 701 struct RadioButtonsModel { 702 string[] _dom_classes; // CSS classes applied to widget DOM element 703 enum _model_module = "@jupyter-widgets/controls"; 704 enum _model_module_version = "1.2.0"; 705 enum _model_name = "RadioButtonsModel"; 706 string[] _options_labels; // The labels for the options. 707 enum _view_module = "@jupyter-widgets/controls"; 708 enum _view_module_version = "1.2.0"; 709 enum _view_name = "RadioButtonsView"; 710 string description; // Description of the control. 711 bool disabled = false; // Enable or disable user changes 712 Nullable!(int) index; // Selected index 713 Reference!LayoutModel layout; 714 Reference!DescriptionStyleModel style; // Styling customizations 715 } 716 717 struct SelectModel { 718 string[] _dom_classes; // CSS classes applied to widget DOM element 719 enum _model_module = "@jupyter-widgets/controls"; 720 enum _model_module_version = "1.2.0"; 721 enum _model_name = "SelectModel"; 722 string[] _options_labels; // The labels for the options. 723 enum _view_module = "@jupyter-widgets/controls"; 724 enum _view_module_version = "1.2.0"; 725 enum _view_name = "SelectView"; 726 string description; // Description of the control. 727 bool disabled = false; // Enable or disable user changes 728 Nullable!(int) index; // Selected index 729 Reference!LayoutModel layout; 730 int rows = 5; // The number of rows to display. 731 Reference!DescriptionStyleModel style; // Styling customizations 732 } 733 734 struct SelectMultipleModel { 735 string[] _dom_classes; // CSS classes applied to widget DOM element 736 enum _model_module = "@jupyter-widgets/controls"; 737 enum _model_module_version = "1.2.0"; 738 enum _model_name = "SelectMultipleModel"; 739 string[] _options_labels; // The labels for the options. 740 enum _view_module = "@jupyter-widgets/controls"; 741 enum _view_module_version = "1.2.0"; 742 enum _view_name = "SelectMultipleView"; 743 string description; // Description of the control. 744 bool disabled = false; // Enable or disable user changes 745 int[] index; // Selected indices 746 Reference!LayoutModel layout; 747 int rows = 5; // The number of rows to display. 748 Reference!DescriptionStyleModel style; // Styling customizations 749 } 750 751 struct SelectionRangeSliderModel { 752 string[] _dom_classes; // CSS classes applied to widget DOM element 753 enum _model_module = "@jupyter-widgets/controls"; 754 enum _model_module_version = "1.2.0"; 755 enum _model_name = "SelectionRangeSliderModel"; 756 string[] _options_labels; // The labels for the options. 757 enum _view_module = "@jupyter-widgets/controls"; 758 enum _view_module_version = "1.2.0"; 759 enum _view_name = "SelectionRangeSliderView"; 760 bool continuous_update = true; // Update the value of the widget as the user is holding the slider. 761 string description; // Description of the control. 762 bool disabled = false; // Enable or disable user changes 763 int[2] index = [0, 0]; // Min and max selected indices 764 Reference!LayoutModel layout; 765 string orientation = Orientation.horizontal; // Vertical or horizontal. 766 bool readout = true; // Display the current selected label next to the slider 767 Reference!DescriptionStyleModel style; // Styling customizations 768 } 769 770 struct SelectionSliderModel { 771 string[] _dom_classes; // CSS classes applied to widget DOM element 772 enum _model_module = "@jupyter-widgets/controls"; 773 enum _model_module_version = "1.2.0"; 774 enum _model_name = "SelectionSliderModel"; 775 string[] _options_labels; // The labels for the options. 776 enum _view_module = "@jupyter-widgets/controls"; 777 enum _view_module_version = "1.2.0"; 778 enum _view_name = "SelectionSliderView"; 779 bool continuous_update = true; // Update the value of the widget as the user is holding the slider. 780 string description; // Description of the control. 781 bool disabled = false; // Enable or disable user changes 782 int index = 0; // Selected index 783 Reference!LayoutModel layout; 784 string orientation = Orientation.horizontal; // Vertical or horizontal. 785 bool readout = true; // Display the current selected label next to the slider 786 Reference!DescriptionStyleModel style; // Styling customizations 787 } 788 789 struct SliderStyleModel { 790 enum _model_module = "@jupyter-widgets/controls"; 791 enum _model_module_version = "1.2.0"; 792 enum _model_name = "SliderStyleModel"; 793 enum _view_module = "@jupyter-widgets/base"; 794 enum _view_module_version = "1.0.0"; 795 enum _view_name = "StyleView"; 796 string description_width; // Width of the description to the side of the control. 797 Nullable!(string) handle_color; // Color of the slider handle. 798 } 799 800 // TODO: WidgetModel[] is not implemented. Probably could be a IWidget[] 801 // struct TabModel { 802 // string[] _dom_classes; // CSS classes applied to widget DOM element 803 // enum _model_module = "@jupyter-widgets/controls"; 804 // enum _model_module_version = "1.2.0"; 805 // enum _model_name = "TabModel"; 806 // JSONValue _titles = {}; // Titles of the pages 807 // enum _view_module = "@jupyter-widgets/controls"; 808 // enum _view_module_version = "1.2.0"; 809 // enum _view_name = "TabView"; 810 // string box_style = BoxStyle.none; // Use a predefined styling for the box. 811 // WidgetModel[] children; // List of widget children 812 // Reference!LayoutModel layout; 813 // Nullable!(int) selected_index = 0; // The index of the selected page. This is either an integer selecting a particular sub-widget, or None to have no widgets selected. 814 // } 815 816 struct TextModel { 817 string[] _dom_classes; // CSS classes applied to widget DOM element 818 enum _model_module = "@jupyter-widgets/controls"; 819 enum _model_module_version = "1.2.0"; 820 enum _model_name = "TextModel"; 821 enum _view_module = "@jupyter-widgets/controls"; 822 enum _view_module_version = "1.2.0"; 823 enum _view_name = "TextView"; 824 bool continuous_update = true; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 825 string description; // Description of the control. 826 bool disabled = false; // Enable or disable user changes 827 Reference!LayoutModel layout; 828 string placeholder = "\u200b"; // Placeholder text to display when nothing has been typed 829 Reference!DescriptionStyleModel style; // Styling customizations 830 string value; // String value 831 } 832 833 struct TextareaModel { 834 string[] _dom_classes; // CSS classes applied to widget DOM element 835 enum _model_module = "@jupyter-widgets/controls"; 836 enum _model_module_version = "1.2.0"; 837 enum _model_name = "TextareaModel"; 838 enum _view_module = "@jupyter-widgets/controls"; 839 enum _view_module_version = "1.2.0"; 840 enum _view_name = "TextareaView"; 841 bool continuous_update = true; // Update the value as the user types. If False, update on submission, e.g., pressing Enter or navigating away. 842 string description; // Description of the control. 843 bool disabled = false; // Enable or disable user changes 844 Reference!LayoutModel layout; 845 string placeholder = "\u200b"; // Placeholder text to display when nothing has been typed 846 Nullable!(int) rows; // The number of rows to display. 847 Reference!DescriptionStyleModel style; // Styling customizations 848 string value; // String value 849 } 850 851 struct ToggleButtonModel { 852 string[] _dom_classes; // CSS classes applied to widget DOM element 853 enum _model_module = "@jupyter-widgets/controls"; 854 enum _model_module_version = "1.2.0"; 855 enum _model_name = "ToggleButtonModel"; 856 enum _view_module = "@jupyter-widgets/controls"; 857 enum _view_module_version = "1.2.0"; 858 enum _view_name = "ToggleButtonView"; 859 string button_style = ButtonStyle.none; // Use a predefined styling for the button. 860 string description; // Description of the control. 861 bool disabled = false; // Enable or disable user changes. 862 string icon; // Font-awesome icon. 863 Reference!LayoutModel layout; 864 Reference!DescriptionStyleModel style; // Styling customizations 865 string tooltip; // Tooltip caption of the toggle button. 866 bool value = false; // Bool value 867 } 868 869 struct ToggleButtonsModel { 870 string[] _dom_classes; // CSS classes applied to widget DOM element 871 enum _model_module = "@jupyter-widgets/controls"; 872 enum _model_module_version = "1.2.0"; 873 enum _model_name = "ToggleButtonsModel"; 874 string[] _options_labels; // The labels for the options. 875 enum _view_module = "@jupyter-widgets/controls"; 876 enum _view_module_version = "1.2.0"; 877 enum _view_name = "ToggleButtonsView"; 878 Nullable!(string) button_style = Nullable!(string)(ButtonStyle.none); // Use a predefined styling for the buttons. 879 string description; // Description of the control. 880 bool disabled = false; // Enable or disable user changes 881 string[] icons; // Icons names for each button (FontAwesome names without the fa- prefix). 882 Nullable!(int) index; // Selected index 883 Reference!LayoutModel layout; 884 Reference!ToggleButtonsStyleModel style; 885 string[] tooltips; // Tooltips for each button. 886 } 887 888 struct ToggleButtonsStyleModel { 889 enum _model_module = "@jupyter-widgets/controls"; 890 enum _model_module_version = "1.2.0"; 891 enum _model_name = "ToggleButtonsStyleModel"; 892 enum _view_module = "@jupyter-widgets/base"; 893 enum _view_module_version = "1.0.0"; 894 enum _view_name = "StyleView"; 895 string button_width; // The width of each button. 896 string description_width; // Width of the description to the side of the control. 897 string font_weight; // Text font weight of each button. 898 } 899 900 // TODO: WidgetModel[] is not implemented. Probably could be a IWidget[] 901 // struct VBoxModel { 902 // string[] _dom_classes; // CSS classes applied to widget DOM element 903 // enum _model_module = "@jupyter-widgets/controls"; 904 // enum _model_module_version = "1.2.0"; 905 // enum _model_name = "VBoxModel"; 906 // enum _view_module = "@jupyter-widgets/controls"; 907 // enum _view_module_version = "1.2.0"; 908 // enum _view_name = "VBoxView"; 909 // string box_style = BoxStyle.none; // Use a predefined styling for the box. 910 // WidgetModel[] children; // List of widget children 911 // Reference!LayoutModel layout; 912 // } 913 914 struct ValidModel { 915 string[] _dom_classes; // CSS classes applied to widget DOM element 916 enum _model_module = "@jupyter-widgets/controls"; 917 enum _model_module_version = "1.2.0"; 918 enum _model_name = "ValidModel"; 919 enum _view_module = "@jupyter-widgets/controls"; 920 enum _view_module_version = "1.2.0"; 921 enum _view_name = "ValidView"; 922 string description; // Description of the control. 923 bool disabled = false; // Enable or disable user changes. 924 Reference!LayoutModel layout; 925 string readout = "Invalid"; // Message displayed when the value is False 926 Reference!DescriptionStyleModel style; // Styling customizations 927 bool value = false; // Bool value 928 } 929 930 struct OutputModel { 931 string[] _dom_classes; // CSS classes applied to widget DOM element 932 enum _model_module = "@jupyter-widgets/output"; 933 enum _model_module_version = "1.0.0"; 934 enum _model_name = "OutputModel"; 935 enum _view_module = "@jupyter-widgets/output"; 936 enum _view_module_version = "1.0.0"; 937 enum _view_name = "OutputView"; 938 Reference!LayoutModel layout; 939 string msg_id; // Parent message id of messages to capture 940 JSONValue[] outputs; // The output messages synced from the frontend. 941 } 942 943 enum isModel(alias T) = __traits(compiles, T._model_module); 944 enum isModel(T) = __traits(compiles, T._model_module); 945 946 JSONValue toJSONValue(T)(ref T field) { 947 static if (is(T : Reference!P, P)) 948 return JSONValue(field.value); 949 else static if (isModel!T) 950 return field.serialize(); 951 else static if (is(T : Nullable!S, S)) { 952 if (field.isNull) 953 return JSONValue(null); 954 return field.get.toJSONValue(); 955 } else 956 return JSONValue(field); 957 } 958 959 T fromJSONValue(T)(in ref JSONValue value) { 960 static if (is (T : int[2])) { 961 int[2] range = [cast(int)value[0].integer, cast(int)value[1].integer]; 962 return range; 963 } 964 static if (is (T : double[2])) { 965 double[2] range = [cast(double)value[0].floating, cast(double)value[1].floating]; 966 return range; 967 } 968 static if (is(T : Reference!P, P)) 969 return Reference!P(value.str); 970 static if (is(T == double)) { 971 if (value.type == JSONType.integer) 972 return cast(float)value.integer(); 973 return value.floating(); 974 } else static if (is(T == int)) 975 return cast(int)value.integer(); 976 else static if (is(T == immutable(char)[])) 977 return value.str(); 978 else static if (is(T == string)) 979 return value.str(); 980 else static if (is(T == bool)) 981 return value.boolean(); 982 else static if (is(T == enum)) 983 return cast(T)value.str(); 984 else static if (is(T == JSONValue[])) 985 return (() @trusted => value.array)().dup; 986 else static if (is(T == P[], P)) 987 return (() @trusted => value.array)().map!(value => value.fromJSONValue!P).array(); 988 else static if (is(T == Nullable!P, P)) { 989 if (value.isNull) 990 return Nullable!P(); 991 return Nullable!P(value.fromJSONValue!P); 992 } 993 static assert("Don't know how to deserialize "~T.stringof); 994 } 995 996 JSONValue serialize(T)(ref T obj) if (isModel!T) { 997 JSONValue data; 998 JSONValue state; 999 state["_model_module"] = obj._model_module; 1000 state["_model_module_version"] = obj._model_module_version; 1001 state["_model_name"] = obj._model_name; 1002 state["_view_module"] = obj._view_module; 1003 state["_view_module_version"] = obj._view_module_version; 1004 state["_view_name"] = obj._view_name; 1005 1006 foreach (idx, field; obj.tupleof) { 1007 state[__traits(identifier, obj.tupleof[idx])] = field.toJSONValue(); 1008 } 1009 data["state"] = state; 1010 data["buffer_paths"] = parseJSON(`[]`); // NOTE: we need to use buffer_paths whenever we move raw bytes 1011 return data; 1012 } 1013 1014 @safe unittest { 1015 FloatSliderModel slider; 1016 slider.serialize(); 1017 } 1018 1019 void update(T)(ref T state, JSONValue newState, JSONValue buffer_paths) if (isModel!T) { 1020 if (newState.type != JSONType.object) 1021 throw new Error("Excepted JSON object"); 1022 const object = (() @trusted => newState.object)(); 1023 foreach (idx, field; state.tupleof) { 1024 enum FieldName = __traits(identifier, state.tupleof[idx]); 1025 alias FieldType = typeof(state.tupleof[idx]); 1026 if (auto p = FieldName in object) { 1027 static if (isModel!(FieldType)) { 1028 __traits(getMember, state, FieldName).update(*p, buffer_paths); 1029 } else 1030 __traits(getMember, state, FieldName) = (*p).fromJSONValue!(FieldType); 1031 } 1032 } 1033 } 1034 1035 @safe unittest { 1036 FloatSliderModel slider; 1037 slider.update(parseJSON(`{"max":300.0}`), parseJSON("{}")); 1038 assert(slider.max == 300.0); 1039 } 1040 1041 alias getModuleMember(string name) = __traits(getMember, mixin(__MODULE__), name); 1042 enum filterSelf(string name) = name != "AllModels"; 1043 alias AllModels = Filter!(isModel, staticMap!(getModuleMember, Filter!(filterSelf, __traits(allMembers, mixin(__MODULE__)))));